/*******************    (C) COPYRIGHT SUNSHINE SILICON    **********************
* File Name: main.c
* Description:

    HS6200 Demo Remoter
    
*  Copyright (C) 2014-2035 Sunshine Silicon Corporation (www.sunsili.com), All Rights Reserved
*  SPDX-License-Identifier: Apache-2.0
*
*  Licensed under the Apache License, Version 2.0 (the "License"); you may
*  not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
*  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*  This file is part of HS6200 SDK                                                                                                                             
 *                                                                                                                                  
 *                                                                                                                                  
 *                                    ___________________________                           \ /    
 *                                   |                           |        _____________      |                             
 *                                   |                           |       |             |     |                                  
 *                                   |                     P0.0  | --->  |  nCE        |-----|                                     
 *                                   |                S  | P0.1  | --->  |  SCK | S    |   H                                     
 *                                   |                P  | P0.2  | <---  |  MISO| P    |   S                                     
 *                                   |                I  | P0.3  | --->  |  MOSI| I    |   6  (as PRX)                     
 *                                   |                   | P0.7  | --->  |  nSS |      |   2                                     
 *             /-------------------- | VBUS                P0.6  | <---  |  IRQ        |   0                                     
 *      P ____/________USB__________ | D+                        |       |_____________|   0                                     
 *      C     \        Bus           | D-                        |                                               
 *             \-------------------- | GND                       |                                         
 *                                   |                           |                                     
 *                                   |                           |                                                     
 *                                   |                           |                                           
 *                                   |                           |                                                              
 *                                   |                     P1.0  | ---> SYSCLK Output,used for test.                            
 *                                   |                           |                                                                  
 *                                   |                           |                                                               
 *                                   |                     P2.2  | ---> LED1 ( LED On when P2.2 output 0 )                       
 *                                   |                     P2.3  | ---> LED2 ( LED On when P2.3 output 0 )                       
 *                                   |                           |                                                               
 *                                   |___________________________|                                                                   
 *                                                                                                                                 
 *                                             C8051F380                                                                                        
 *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
 */     

#include "compiler_defs.h"
#include "C8051F380_defs.h"
#include "HS6200.h"
#include "Init_Device.h"
//#include "HS6200_Reg.h"
#include "C8051F_delay.h"
#include "C8051F_Delay.h"
#include "C8051F38X_clock.h"
#include "hw_timer.h"
#include "stdio.h"


#define SYSCLK      48000000           // SYSCLK frequency in Hz

#define HOPPING_COUNTER_MAX 3 /*24MS*/
#define SCAN_CHANNEL_INDEX 0x50

#define MAX_RT    0x10
#define TX_DS   	0x20
#define RX_DR   	0x40

#define OUT_LINE_CH 80
#define Remoter_Tx_Payload_Length 10

typedef enum
{
	ON_LINK,
	OUT_LINK
}LindStatusT;
LindStatusT Linkstatus;

typedef enum
{
	START,
	STOP
}HoppingFlagT;

typedef struct
{
	HoppingFlagT Hopping_Start_Flag;
	U8 RF_Freq_Hop_Channal_Idx;
	U8 HoppingWait;
	U8 HoppingCounter;
}ChannelCtlT;
ChannelCtlT ChannelCtl;

typedef enum
{
	ADDR_OUT_LINK,
	ADDR_ON_LINK
}AddrT;
AddrT Current_Addr_Flag;

typedef enum
{
	Msg_T0,
	Msg_T1,
	Msg_T2,
	Msg_T3,
}MsgT;
MsgT RecMsgType;

typedef struct
{
	MsgT MsgType;
	U8 MsgTypeIndex;
}MsgTypeCtlT;
MsgTypeCtlT MsgTypeCtl;

typedef struct
{
	U8 timeout_flag;
	U8 timeWait;
	U8 firstSendFlag;
}TimeSlotCtlT;
TimeSlotCtlT TimeSlotCtl;

U8 SPI_Flag=SPI_FLG_IDLE;

U8 HS6200_Board_Addr[5]= {0x55,0x42,0x9C,0x8F,0xC9};                //default address
U8 RF_Freq_Hop_Channal_on_link[5]= {0x55,0x83,0x2A,0x66,0x4B};                //default address

U8 RF_Freq_Hop_Channal[]={80, 22,43, 67, 77};
//U8 RF_Freq_Hop_Channal[]={80, 80,80, 80, 80};


S8 HS6200_Tx_Payload[32];
U8 HS6200_Rx_Payload[32];
U8 HS6200_Rx_Payload_Width=0x00;
U8 HS6200_Tx_Payload_Width;
U8 slot_conter;

#if 0
/******************************************************
*modifed by lidianjun 2014,5,28 for make the timer more accurate
*******************************************************/
void Timer0_Init10Ms()
{
	unsigned int count;
    
	CKCON = 0;

	TMOD &= ~0x0f;
	TMOD|=0x01;
	
	count = 65536 - 40000 + 8;			//10ms
	
	TH0 = (count>>8)&0x00ff;
	TL0 = count&0x00ff;

	ET0 = 1;  /*enable interrupt*/ 
	TR0 = 1;
	
}

void TImer0Disable(void)
{
	TR0 = 0;
	TH0 = 0;
	TL0 = 0;
}
#endif
void HS_ASSERT(U8 c)
{
	if (!c)
	{
		TImer0Disable();
		while(1);
	}
}

void ChannelIndexPlus(void)
{
	ChannelCtl.RF_Freq_Hop_Channal_Idx++; 
	if(ChannelCtl.RF_Freq_Hop_Channal_Idx >= sizeof(RF_Freq_Hop_Channal))
	{
		ChannelCtl.RF_Freq_Hop_Channal_Idx = 0; 
	} 
	LED_TIME_DEBUG1_TRIG;
}

void MsgTypeIndexPlus(void)
{
	MsgTypeCtl.MsgTypeIndex++; 
	if(MsgTypeCtl.MsgTypeIndex >= 4)
	{
		MsgTypeCtl.MsgTypeIndex = 0; /*M0 used for out link mode*/
		//LED_TIME_DEBUG1_TRIG;
	} 
	LED_TIME_DEBUG1_TRIG;
}


void ParamInit()
{
	U8 i;
	
	Linkstatus = OUT_LINK;
	
	ChannelCtl.Hopping_Start_Flag = STOP;
	ChannelCtl.RF_Freq_Hop_Channal_Idx = 0;
	ChannelCtl.HoppingWait = 0;
	ChannelCtl.HoppingCounter = 0;

	Current_Addr_Flag = ADDR_OUT_LINK;

	TimeSlotCtl.timeWait = 0;
	TimeSlotCtl.timeout_flag = 0;
	TimeSlotCtl.firstSendFlag = 0;
	
	MsgTypeCtl.MsgTypeIndex = Msg_T0;

	for(i=0x00;i<32;i++)
		HS6200_Tx_Payload[i]=i;
	HS6200_Tx_Payload[9] = Msg_T0;

	LED_TIME_DEBUG1_OFF;
	LED_TIME_DEBUG_OFF;
	
}

void Updata_TX_Payload(U8 Msg_type)
{
	U8 i;
	for(i=0x00;i<32;i++)
		HS6200_Tx_Payload[i]=0xFF;
	HS6200_Tx_Payload[9] = Msg_type;
}


void Out_Link_Thread(void)
{
	U8 status=0x00;

	
	
	while(0 == TimeSlotCtl.timeout_flag);
	TimeSlotCtl.timeout_flag = 0;
	
	status=HS6200_Read_Status(); /*check HS6200 status */
	printf("\r\n%bx",status);
	
	/*rec ack*/
	if(status & TX_DS) 
	{
		LED2_ON;
		LED1_OFF;
		/*clear status*/
		HS6200_Clear_All_Irq();  
		HS6200_Flush_Tx();
		HS6200_Flush_Rx();

		/*send msg*/
		HS6200_SendPack(HS6200_W_TX_PAYLOAD,HS6200_Tx_Payload,Remoter_Tx_Payload_Length);
		HS6200_CE_High();

		/*update device info*/
		Linkstatus = ON_LINK;
		
		return;		
	}
	#if 0
	else if (status & MAX_RT)
	{
		HS6200_Clear_All_Irq();
		HS6200_Flush_Tx_Fifo();
		HS6200_Flush_Rx_Fifo();

		/*send msg*/
		HS6200_Write_Tx_Payload(HS6200_Tx_Payload,Remoter_Tx_Payload_Length);
		HS6200_CE_High();
	}
	#endif 
	/*not receive ack*/ 
	else 	
	{
		HS6200_Clear_All_Irq();
		/*clear status*/
		HS6200_Flush_Tx();
		HS6200_Flush_Rx();

		/*send msg*/
		HS6200_SendPack(HS6200_W_TX_PAYLOAD,HS6200_Tx_Payload,Remoter_Tx_Payload_Length);
		HS6200_CE_High();

		return;
		
	}
	
}


void On_Link_Thread(void)
{
	U8 status=0x00;

	while(TimeSlotCtl.timeout_flag==0);
	TimeSlotCtl.timeout_flag = 0;

	status=HS6200_Read_Status(); /*check HS6200 status */
	printf("\r\n%bx",status);

	/*rec ack*/
	if(status & TX_DS) 
	{
		LED2_ON;
		LED1_OFF;

		/*clear status*/
		HS6200_Clear_All_Irq();  
		HS6200_Flush_Tx();
		HS6200_Flush_Rx();

		/*send msg*/
		HS6200_SendPack(HS6200_W_TX_PAYLOAD,HS6200_Tx_Payload,Remoter_Tx_Payload_Length);
		HS6200_CE_High();
		
		return;		
	}
	else
	{	
		LED2_ON;
		LED1_ON;
		
		/*clear status*/
		HS6200_Clear_All_Irq();  
		HS6200_Flush_Tx();
		HS6200_Flush_Rx();

		ChannelIndexPlus();
		HS6200_Change_CH(RF_Freq_Hop_Channal[ChannelCtl.RF_Freq_Hop_Channal_Idx]);
		
		/*send msg*/
		HS6200_SendPack(HS6200_W_TX_PAYLOAD,HS6200_Tx_Payload,Remoter_Tx_Payload_Length);
		HS6200_CE_High();
	}

	
	return;

}


void main(void)
{
	SysClkInit(); 
	Init_Device();
	
	Delay_ms(100);

	HS6200_CE_Low();
	HS6200_Init();
	HS6200_CE_High();

	ParamInit();

	Timer0_InitMs();

	HS6200_Change_CH(OUT_LINE_CH);

	printf("www.huntersun.com\r\n");

	LED1_ON;
		
	while(1)
	{
		if(OUT_LINK == Linkstatus)  /*check ID*/  		
		{
			Out_Link_Thread();	
		}
		else if (ON_LINK == Linkstatus) /*send msg*/
		{
			On_Link_Thread();
		}
		else 
		{
			;
		}
	}
}

/*-----------------------SPI ISR-------------------------*/
void SPI_Isr(void) interrupt 6// SPI interrupt
{
	if(SPIF==0x01)	   //SPI interrupt flag
	{
		SPI_Flag=SPI_FLG_IDLE;
		SPIF=0x00;  //clear									
	}
	if(RXOVRN==0x01)   //rx overflow
	{
		
	}						
}

/*-----------------------Timer0 ISR-------------------------*/
void Timer0_ISR (void) interrupt 1 using 3
{  

	
	TImer0Disable();
	Timer0_InitMs(); 
	
	TimeSlotCtl.timeout_flag = 1;
	//LED_TIME_DEBUG_TRIG;
}
/*---------------------------------------End Of File----------------------------------------*/

